package cn.jlearn.proxy.agent.handler;

import cn.jlearn.proxy.agent.handler.bs.ClientConnectSuccessResHandler;
import cn.jlearn.proxy.agent.handler.bs.TcpReqHandler;
import cn.jlearn.proxy.agent.handler.bs.TcpTunnelCloseReqHandler;
import cn.jlearn.proxy.agent.handler.bs.TcpTunnelOpenReqHandler;
import cn.jlearn.proxy.common.enums.MsgTypeEnum;
import cn.jlearn.proxy.common.handler.AbstractAioHandler;
import cn.jlearn.proxy.common.handler.AbstractBsHandler;
import cn.jlearn.proxy.common.packet.BsPacket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.client.intf.ClientAioHandler;
import org.tio.core.ChannelContext;
import org.tio.core.intf.Packet;

import java.util.HashMap;
import java.util.Map;

/**
 * @author qianyingchao
 * @version 1.0
 * @date 2021/5/10 4:24 下午
 */
public class ProxyClientHandler extends AbstractAioHandler implements ClientAioHandler {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final BsPacket packet = new BsPacket(MsgTypeEnum.HEART_BEAT_REQ.getCode(), null);

    private final Map<Byte, AbstractBsHandler<?>> handlerMap = new HashMap<>(2);

    public ProxyClientHandler() {
        handlerMap.put(MsgTypeEnum.HEART_BEAT_REQ.getCode(), null);
        handlerMap.put(MsgTypeEnum.TCP_FORWARD_REQ.getCode(), new TcpReqHandler());
        handlerMap.put(MsgTypeEnum.TCP_TUNNEL_CLOSE_REQ.getCode(), new TcpTunnelCloseReqHandler());
        handlerMap.put(MsgTypeEnum.TCP_TUNNEL_OPEN_REQ.getCode(), new TcpTunnelOpenReqHandler());
        handlerMap.put(MsgTypeEnum.TCP_CLIENT_CONNECT_SUCCESS_RES.getCode(), new ClientConnectSuccessResHandler());
    }

    @Override
    public Packet heartbeatPacket(ChannelContext channelContext) {
        return packet;
    }

    @Override
    public void handler(Packet p, ChannelContext channelContext) throws Exception {
        BsPacket packet = (BsPacket) p;
        Byte type = packet.getType();
        AbstractBsHandler<?> abstractBsHandler = handlerMap.get(type);
        if (abstractBsHandler == null) {
            logger.error("{}, 找不到处理类，type:{}", channelContext, type);
            return;
        }
        abstractBsHandler.handler(packet, channelContext);
    }

}
